package com.xms.web.framework.filter;

import com.xms.core.annotation.AllowAnonymous;
import com.xms.security.identity.IAuthenticationService;
import com.xms.utils.JsonUtil;
import com.xms.utils.StringUtil;
import com.xms.web.framework.model.JsonResultObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * <p>
 * 登录状态验证拦截器
 * </p>
 *
 * @author migo
 * @since 2021/9/11
 */
@Component
public class AuthenticatedInterceptor implements HandlerInterceptor {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    private IAuthenticationService _authenticationService;

    @Autowired
    public void AuthenticatedInterceptor(IAuthenticationService authenticationService) {
        _authenticationService = authenticationService;
    }

    @Override
    public boolean preHandle(HttpServletRequest servletRequest, HttpServletResponse servletResponse, Object o) throws Exception {
        if (!(o instanceof HandlerMethod)) {
            return true;
        }
        boolean allowAnnoymous = ((HandlerMethod) o).getBean().getClass().isAnnotationPresent(AllowAnonymous.class);
        if (!allowAnnoymous) {
            allowAnnoymous = ((HandlerMethod) o).getMethod().isAnnotationPresent(AllowAnonymous.class);
        }
        if (allowAnnoymous) {
            return true;
        }

        String path = servletRequest.getRequestURI();
        // 如果访问登录页面或者静态资源则跳过
        if (path.indexOf("/signin") >= 0 || path.indexOf("/error") >= 0 || path.indexOf("/content/") >= 0) {
            return true;
        } else {
            if (_authenticationService.isAuthenticated(servletRequest)) {
                return true;
            } else {
                HttpServletResponseWrapper httpResponse = new HttpServletResponseWrapper((HttpServletResponse) servletResponse);
                if (path.indexOf("/api") >= 0) {
                    writeJson(httpResponse, JsonUtil.toJSONString(JsonResultObject.failure("session timeout", 1)));
                } else {
                    //httpRequest.getRequestDispatcher("/signin").forward(servletRequest, servletResponse);
                    String queryString = servletRequest.getQueryString();
                    if(StringUtil.notEmpty(queryString)){
                        path += "?" + queryString;
                    }
                    httpResponse.sendRedirect("/signin?url=" + StringUtil.urlEncode(path));
                }
                return false;
            }
        }
    }

    private void writeJson(HttpServletResponse response, String json) {
        PrintWriter writer = null;
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        try {
            writer = response.getWriter();
            writer.print(json);

        } catch (IOException e) {
            logger.error("response error", e);
        } finally {
            if (writer != null)
                writer.close();
        }
    }
}
